package com.ncmmall.api.apis.mall;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.ncmmall.api.apis.service.Result;
import com.ncmmall.api.params.UploadDataDTO;
import com.ncmmall.api.security.Securitys;
import com.ncmmall.application.business.member.MemberApplication;
import com.ncmmall.domain.security.user.WebUser;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;

/**
 * @author linxs
 * 文件上传接口
 */
@RestController
@RequestMapping(value = "/upload")
@Slf4j
public class ImageUploadApi {

    @Autowired
    private MemberApplication memberApplication;

    @Value("${store.domain}")
    private String storeDomain;

    @Value("${store.path}")
    private String storePath;

    /**
     * 通用图片上传
     */
    @RequestMapping(value = "/image", method = RequestMethod.POST)
    @ResponseBody
    public Result image(@RequestBody UploadDataDTO upload) {
        Result result = new Result();
        try {
            upload.setType("uploads");
            ToImage toImage = new ToImage(upload).invoke();
            String imagePath = toImage.getImagePath();

            return result.ok().inject(ImmutableMap.of("src", storeDomain + "/" + imagePath, "name", toImage.getName()));

        } catch (Exception e) {
            log.error("[照片上传异常]", e);
            return result.fail();
        }
    }

    /**
     * 用户头像上传
     */
    @RequestMapping(value = "/avatar", method = RequestMethod.POST)
    @ResponseBody
    public Result avatar(HttpServletRequest request, @RequestBody UploadDataDTO upload) {

        Result result = new Result();
        try {
            upload.setType("avatar");
            ToImage toImage = new ToImage(upload).invoke();
            String imagePath = toImage.getImagePath();

            WebUser user = Securitys.user(request);
            memberApplication.modifyAvatar(user, toImage.getName());

            return result.ok().inject(ImmutableMap.of("src", storeDomain + "/" + imagePath, "name", toImage.getName()));

        } catch (Exception e) {
            log.error("[头像照片上传异常]", e);
            return result.fail();
        }
    }

    @RequestMapping(value = "/uploadAvatar", method = RequestMethod.POST)
    @ResponseBody
    public Result uploadAvatar(@RequestBody UploadDataDTO upload) {

        Result result = new Result();
        try {
            upload.setType("avatar");
            ToImage toImage = new ToImage(upload).invoke();
            String imagePath = toImage.getImagePath();

            return result.ok().inject(ImmutableMap.of("src", storeDomain + "/" + imagePath, "name", toImage.getName()));

        } catch (Exception e) {
            log.error("[头像照片上传异常]", e);
            return result.fail();
        }
    }


    private class ToImage {

        private String imagePath;
        private String name;
        private final UploadDataDTO upload;

        public ToImage(UploadDataDTO upload) {
            this.upload = upload;
        }

        public String getImagePath() {
            return imagePath;
        }

        public String getName() {
            return name;
        }

        public ToImage invoke() throws IOException {

            String suffix = ".jpg";
            String imageData = upload.getData();
            String[] data = StrUtil.split(imageData, ",");

            if (data.length > 1) {
                imageData = data[1];
            }

            File dir = new File(storePath + File.separator + upload.getType());
            FileUtil.mkdir(dir);

            this.name = System.currentTimeMillis() + suffix;
            imagePath = upload.getType() + File.separator + name;
            try (OutputStream os = new FileOutputStream(storePath + File.separator + imagePath)) {
                os.write(Base64.getMimeDecoder().decode(imageData));
            }
            return this;
        }
    }
}
